/**
 * Project Name:jiuselu-parent
 * File Name:DateUtil.java
 * Package Name:com.fxp.project.jiuselu.commons.date
 * Date:2021年11月18日 15:28
 * Copyright (c) 2021, Kai.Wang All Rights Reserved.
 */
package com.fxp.project.jiuselu.commons.date;

import org.apache.commons.lang3.StringUtils;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

/**
 * ClassName:DateUtil<br/>
 * Function: 日期的工具类<br/>
 * Date:2021年11月18日 15:28<br/>
 *
 * @author Kai.Wang
 * @version 1.0.0
 * @see
 * @since JDK 8
 */
public class DateUtil {
    public static String toDate(Long dateTime) {
        if (null != dateTime) {
            int dday = Integer.parseInt((dateTime / (60 * 60 * 1000 * 24)) + "");
            int dhour = Integer.parseInt(((dateTime % (60 * 60 * 1000 * 24)) / (60 * 60 * 1000)) + "");
            int dmin = Integer.parseInt((((dateTime % (60 * 60 * 1000 * 24)) % (60 * 60 * 1000)) / (60 * 1000)) + "");
            int dsec = Integer.parseInt(((((dateTime % (60 * 60 * 1000 * 24)) % (60 * 60 * 1000)) % (60 * 1000)) / 1000) + "");
            if (dday <= 0 && dhour <= 0 && dmin <= 0 && dsec <= 1) {
                //当前时间不足
                return "";
            } else {
                return dday + "天" + dhour + "小时" + dmin + "分" + dsec + "秒";
            }
        }
        return "";
    }

    public static boolean timeInterval(String startTime, String endTime){
        Calendar date=Calendar.getInstance();
        Calendar date1 = setCalendar(date, startTime);
        Calendar date2 = setCalendar(date, endTime);
        return date.after(date1)&&date.before(date2);
    }

    public static Calendar setCalendar(Calendar date, String time){
        Calendar date1=(Calendar) date.clone();
        String[] a = time.split(":");
        if(!"".equals(a[0]) && a.length>0){
            date1.set(Calendar.HOUR_OF_DAY, Integer.valueOf(a[0]));
        }else{
            date1.set(Calendar.HOUR_OF_DAY, 0);
        }
        if(a.length>1){
            date1.set(Calendar.MINUTE, Integer.valueOf(a[1]));
        }else{
            date1.set(Calendar.MINUTE, 0);
        }
        if(a.length>2){
            date1.set(Calendar.SECOND, Integer.valueOf(a[2]));
        }else{
            date1.set(Calendar.SECOND, 0);
        }
        return date1;
    }

    /**
     * 格式化指定的日期格式字符串
     *
     * @param d
     * @param format
     * @return
     */
    public static String formatDate(Date d, DateFormat format) {
        if (null == d) {
            return "";
        }
        return format.format(d);
    }

    /**
     * 格式化日期時間類型長字符串
     *
     * @param d
     * @return
     */
    public static String formartLongDate(Date d) {
        if (null == d) {
            return "";
        }
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(d);
    }

    public static Date formartStringToDate(String d) throws Exception {
        if (StringUtils.isBlank(d)) {
            return null;
        }
        try {
            return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(d);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 格式化日期短型字符串
     *
     * @param d
     * @return
     */
    public static String formatShortDate(Date d) {
        if (null == d) {
            return "";
        }
        return new SimpleDateFormat("yyyy-MM-dd").format(d);
    }

    /**
     * @param startDay 需要比较的时间 不能为空(null),需要正确的日期格式 ,如：2009-09-12
     * @param endDay 被比较的时间 为空(null)则为当前时间
     * @param stype 返回值类型 0为多少天，1为多少个月，2为多少年
     * @return 举例： compareDate("2009-09-12", null, 0);//比较天
     * compareDate("2009-09-12", null, 1);//比较月
     * compareDate("2009-09-12", null, 2);//比较年
     */
    public static int compareDateStr(String startDay, String endDay, int stype) {
        int n = 0;
        String[] u = {"天", "月", "年"};
        String formatStyle = stype == 1 ? "yyyy-MM" : "yyyy-MM-dd";

        endDay = endDay == null ? getCurrentDate("yyyy-MM-dd") : endDay;
        DateFormat df = new SimpleDateFormat(formatStyle);
        Calendar c1 = Calendar.getInstance();
        Calendar c2 = Calendar.getInstance();
        try {
            c1.setTime(df.parse(startDay));
            c2.setTime(df.parse(endDay));
        } catch (Exception e3) {
            System.out.println("wrong occured");
        }
        // List list = new ArrayList();
        while (!c1.after(c2)) { // 循环对比，直到相等，n 就是所要的结果
            // list.add(df.format(c1.getTime())); // 这里可以把间隔的日期存到数组中 打印出来
            n++;
            if (stype == 1) {
                c1.add(Calendar.MONTH, 1); // 比较月份，月份+1
            } else {
                c1.add(Calendar.DATE, 1); // 比较天数，日期+1
            }
        }
        n = n - 1;
        if (stype == 2) {
            n = (int) n / 365;
        }
        System.out.println(startDay + " -- " + endDay + " 相差多少" + u[stype] + ":" + n);
        return n;
    }

    public static void main(String[] args) throws ParseException {
        //结束时间大于当前时间的
        compareDate(new Date(), "2012-05-28", 0);
        //结束时间等于当前时间的
        compareDate(new Date(), "2012-05-30", 0);
        //结束时间小于当前时间的
        compareDate(new Date(), "2012-06-02", 0);
        //没有结束时间的
        //System.out.println(compareDate(new SimpleDateFormat("yyyy-MM-dd").parse("2013-02-05"),new Date(), 0));
        //当前时间    拍摄时间
        System.out.println(compareDate(new Date(), "2013-05-14", 0));
    }

    /**
     * @param sDay
     * @param endDay
     * @param stype
     * @return
     */
    public static int compareDate(Date sDay, String endDay, int stype) {
        String startDay = "";
        String formatStyle = stype == 1 ? "yyyy-MM" : "yyyy-MM-dd";
        DateFormat df = new SimpleDateFormat(formatStyle);
        if (null == sDay) {
            return 0;
        } else {
            startDay = formatDate(sDay, df);
        }
        if ("".equals(startDay)) {
            return 0;
        }
        int n = 0;
//		String[] u = { "天", "月", "年" };

        endDay = null != endDay && !"".equals(endDay) ? endDay : getCurrentDate("yyyy-MM-dd");
        Calendar c1 = Calendar.getInstance();
        Calendar c2 = Calendar.getInstance();
        try {
            c1.setTime(df.parse(startDay));
            c2.setTime(df.parse(endDay));
        } catch (Exception e3) {
            System.out.println("wrong occured");
        }
        // List list = new ArrayList();
        while (!c1.after(c2)) { // 循环对比，直到相等，n 就是所要的结果
            // list.add(df.format(c1.getTime())); // 这里可以把间隔的日期存到数组中 打印出来
            n++;
            if (stype == 1) {
                c1.add(Calendar.MONTH, 1); // 比较月份，月份+1
            } else {
                c1.add(Calendar.DATE, 1); // 比较天数，日期+1
            }
        }
        n = n - 1;
        if (stype == 2) {
            n = (int) n / 365;
        }
//		System.out.println(startDay + " -- " + endDay + " 相差多少" + u[stype]+ ":" + n);
        return n;
    }

    /**
     * @param startDay 需要比较的时间 不能为空(null),需要正确的日期格式 ,如：2009-09-12
     * @param endDay 被比较的时间 为空(null)则为当前时间
     * @param stype 返回值类型 0为多少天，1为多少个月，2为多少年
     * @return 举例： compareDate(new Date(new Date().getTime()-24*60*60*1000), null, 0);//比较天
     * compareDate(new Date(new Date().getTime()-24*60*60*1000), null, 1);//比较月
     * compareDate(new Date(new Date().getTime()-24*60*60*1000), null, 2);//比较年
     */
    public static int compareDate(Date startDay, Date endDay, int stype) {
        int n = 0;
//		String[] u = { "天", "月", "年" };
//		String formatStyle = stype == 1 ? "yyyy-MM" : "yyyy-MM-dd";
        endDay = endDay == null ? new Date() : endDay;
//		DateFormat df = new SimpleDateFormat(formatStyle);
        Calendar c1 = Calendar.getInstance();
        Calendar c2 = Calendar.getInstance();
        try {
            c1.setTime(startDay);
            c2.setTime(endDay);
        } catch (Exception e3) {
            System.out.println("wrong occured");
        }
        // List list = new ArrayList();
        while (!c1.after(c2)) { // 循环对比，直到相等，n 就是所要的结果
            // list.add(df.format(c1.getTime())); // 这里可以把间隔的日期存到数组中 打印出来
            n++;
            if (stype == 1) {
                c1.add(Calendar.MONTH, 1); // 比较月份，月份+1
            } else {
                c1.add(Calendar.DATE, 1); // 比较天数，日期+1
            }
        }
        n = n - 1;
        if (stype == 2) {
            n = (int) n / 365;
        }
//		System.out.println(startDay + " -- " + endDay + " 相差多少" + u[stype]+ ":" + n);
        return n;
    }

    public static String getCurrentDate(String format) {
        Calendar day = Calendar.getInstance();
        day.add(Calendar.DATE, 0);
        SimpleDateFormat sdf = new SimpleDateFormat(format);// "yyyy-MM-dd"
        String date = sdf.format(day.getTime());
        return date;
    }

    public static String getCodeNo() {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmssSSS");
        Date today = new Date();
        String mo = today.getTime() + "";
        String code = dateFormat.format(today) + mo.substring(mo.length() - 3) + (Math.random() + "").substring(2, 5);
        return code;
    }

    /**
     * 获取权限的8位固定ID
     *
     * @return
     */
    public static String getRandomNo() {
        Long random_num = Math.round(Math.random() * 100000000);
        String random_str = random_num.toString();
        int num_len = random_str.length();
        for (int i = 0; i < 8 - num_len; i++) {
            random_str += "0";
        }
        return random_str;
    }

    /**
     * 将日期时间字符串根据转换为指定时区的日期时间.
     *
     * @param srcDateTime   待转化的日期时间.
     * @param dstTimeZoneId 目标的时区编号.
     * @return 转化后的日期时间.
     * @see #string2Timezone(String, String, String, String)
     */
    public static String string2TimezoneDefault(String srcDateTime, String dstTimeZoneId) {
        return string2Timezone("yyyy-MM-dd HH:mm:ss", srcDateTime, "yyyy-MM-dd HH:mm:ss", dstTimeZoneId);
    }

    /**
     * 获取系统当前默认时区与指定时区的时间差.(单位:毫秒)
     *
     * @param timeZoneId 时区Id
     * @return 系统当前默认时区与指定时区的时间差.(单位:毫秒)
     */
    private static int getDiffTimeZoneRawOffset(String timeZoneId) {
        return TimeZone.getDefault().getRawOffset() - TimeZone.getTimeZone(timeZoneId).getRawOffset();
    }

    /**
     * 日期(时间)转化为字符串.
     *
     * @param formater 日期或时间的格式.
     * @param aDate    java.util.Date类的实例.
     * @return 日期转化后的字符串.
     */
    public static String date2String(String formater, Date aDate) {
        if (formater == null || "".equals(formater))
            return null;
        if (aDate == null)
            return null;
        return (new SimpleDateFormat(formater, Locale.CHINA)).format(aDate);
    }

    /**
     * 将日期时间字符串根据转换为指定时区的日期时间.
     *
     * @param srcFormater   待转化的日期时间的格式.
     * @param srcDateTime   待转化的日期时间.
     * @param dstFormater   目标的日期时间的格式.
     * @param dstTimeZoneId 目标的时区编号.
     * @return 转化后的日期时间.
     */
    public static String string2Timezone(String srcFormater, String srcDateTime, String dstFormater, String dstTimeZoneId) {
        if (srcFormater == null || "".equals(srcFormater))
            return null;
        if (srcDateTime == null || "".equals(srcDateTime))
            return null;
        if (dstFormater == null || "".equals(dstFormater))
            return null;
        if (dstTimeZoneId == null || "".equals(dstTimeZoneId))
            return null;
        SimpleDateFormat sdf = new SimpleDateFormat(srcFormater);
        try {
            int diffTime = getDiffTimeZoneRawOffset(dstTimeZoneId);
            Date d = sdf.parse(srcDateTime);
            long nowTime = d.getTime();
            long newNowTime = nowTime - diffTime;
            d = new Date(newNowTime);
            return date2String(dstFormater, d);
        } catch (ParseException e) {
            //Log.output(e.toString(), Log.STD_ERR);
            return null;
        } finally {
            sdf = null;
        }
    }

    /**
     * 将字符串格式的日期转换成java.sql.Date类型
     *
     * @param date 格式形如20130101
     * @return
     */
    public static java.sql.Date parseStringToDate(String date) {
        if (StringUtils.isNotBlank(date)) {
            int dateLength = 8;
            if (date.length() == dateLength) {
                date = date.substring(0, dateLength / 2) + "-" + date.substring(dateLength / 2, dateLength - 2) + "-" + date.substring(dateLength - 2);
            }
            return java.sql.Date.valueOf(date);
        }
        return null;
    }

    /**
     * getWeekOfDate:获取当前日期是星期几. <br/>
     *
     * @param date
     * @return
     * @author Jason.Wang
     * @since JDK 1.7
     */
    public static String getWeekOfDate(Date date) {
        String[] weekOfDays = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
        Calendar calendar = Calendar.getInstance();
        if (date != null) {
            calendar.setTime(date);
        }
        int w = calendar.get(Calendar.DAY_OF_WEEK) - 1;
        if (w < 0) {
            w = 0;
        }
        return weekOfDays[w];
    }
}